/**
 * 
 */
package com.feib.stms.action;

import java.io.File;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.context.support.ResourceBundleMessageSource;

import net.sourceforge.stripes.action.DefaultHandler;
import net.sourceforge.stripes.action.DontBind;
import net.sourceforge.stripes.action.FileBean;
import net.sourceforge.stripes.action.ForwardResolution;
import net.sourceforge.stripes.action.Resolution;
import net.sourceforge.stripes.integration.spring.SpringBean;
import net.sourceforge.stripes.validation.DateTypeConverter;
import net.sourceforge.stripes.validation.Validate;


import com.feib.stms.model.ConfirmRule;
import com.feib.stms.model.Group;
import com.feib.stms.model.PreDesignatedAccount;
import com.feib.stms.model.TempUploadFile;
import com.feib.stms.model.TempUploadFileError;
import com.feib.stms.model.User;
import com.feib.stms.pagination.PaginatedList;
import com.feib.stms.service.ConfirmRuleService;
import com.feib.stms.service.FileImportorService;
import com.feib.stms.service.PreDesignatedAccountService;
import com.feib.stms.service.TempUploadFileErrorService;
import com.feib.stms.service.TempUploadFileService;
import com.feib.stms.service.UploadFileService;
import com.feib.stms.util.FileMD5CheckSumUtil;
import com.feib.stms.util.UserUtil;

/**
 * @author Jimmy Liu
 *
 */
public abstract class BaseUploadActionBean  extends BaseActionBean 
{
	private static final long serialVersionUID = -5075452341389251353L;

	/**
	 * 檢視錯誤原因JSP
	 */
	private static final String UPLOAD_ERROR_JSP = "/WEB-INF/views/stms1001/stms1001Error.jsp";

	/**
	 * 檢視明細JSP
	 */
	private static final String UPLOAD_DETAIL_JSP = "/WEB-INF/views/stms1001/stms1001Detail.jsp";
	
	
	/**
	 * 檢視驗資明細JSP
	 */
	private static final String UPLOAD_CHK_DETAIL_JSP = "/WEB-INF/views/stms1001/stms1001ChkDetail.jsp";


	/**
	 * 上傳檔案</br>
	 * <font color="red">Know when to delete FileBeans</font></br>
	 * If you process a FileBean as an InputStream, call FileBean.delete(). If you use the save() method, don't call FileBean.delete()!
	 */
	protected FileBean attachment;

	@SpringBean("backupBaseDirectory")
	protected String backupBaseDirectory;

	@SpringBean("temporaryBaseDirectory")
	protected String temporaryBaseDirectory;

	@SpringBean("tempUploadFileService")
	protected TempUploadFileService tempUploadFileService;

	@SpringBean("tempUploadFileErrorService")
	protected TempUploadFileErrorService tempUploadFileErrorService;

	@SpringBean("uploadFileService")
	protected UploadFileService uploadFileService;

	@SpringBean("confirmRuleService")
	protected ConfirmRuleService confirmRuleService;

	@SpringBean("messageSource")
	protected ResourceBundleMessageSource messageSource;

	protected String separator = File.separator;

	protected static Map<String, String> SORT_FIELD_NAMES = new LinkedHashMap<String, String>();
	static{
		SORT_FIELD_NAMES.put("uploadDate", "UPLOAD_DATE"); // 上傳日期
		SORT_FIELD_NAMES.put("fileFormat", "FILE_FORMAT"); // 上傳類別
		SORT_FIELD_NAMES.put("fileName", "FILE_NAME"); // 上傳檔名
		SORT_FIELD_NAMES.put("uploadUser", "UPLOAD_USER_PK"); // 上傳人員

		SORT_FIELD_NAMES.put("totalItems", "TOTAL_ITEMS"); // 總筆數
		SORT_FIELD_NAMES.put("totalAmount", "TOTAL_AMOUNT"); // 總金額
		SORT_FIELD_NAMES.put("totalNetPay", "TOTAL_NET_PAY"); // 淨付金額
		SORT_FIELD_NAMES.put("totalNetIncome", "TOTAL_NET_INCOME"); // 淨收金額

		SORT_FIELD_NAMES.put("totalNetPayCount", "TOTAL_NET_PAY_COUNT"); // 淨付筆數
		SORT_FIELD_NAMES.put("totalNetIncomeCount", "TOTAL_NET_INCOME_COUNT"); // 淨收筆數
	}

	/**
	 * 上傳錯誤頁面排序欄位
	 */
	protected static Map<String, String> ERROR_SORT_FIELD_NAMES = new LinkedHashMap<String, String>();
	static{
		ERROR_SORT_FIELD_NAMES.put("lineNumber", "LINE_NUMBER"); // 錯誤行數
		ERROR_SORT_FIELD_NAMES.put("columnName", "COLUMN_NAME"); // 欄位名稱
		ERROR_SORT_FIELD_NAMES.put("errorMessage", "ERROR_MESSAGE"); // 錯誤原因(檢核) 
		ERROR_SORT_FIELD_NAMES.put("exceptionMessage", "EXCEPTION_MESSAGE"); // 程式錯誤原因
	}

	protected static Map<String, String> DETAIL_SORT_FIELD_NAMES = new LinkedHashMap<String, String>();
	static{
		DETAIL_SORT_FIELD_NAMES.put("accountNo", "ACCOUNT_NO"); // 存款帳號
		DETAIL_SORT_FIELD_NAMES.put("deliveryDate", "DELIVERY_DATE"); // 交割日期或扣帳日期
		DETAIL_SORT_FIELD_NAMES.put("netPay", "NET_PAY"); // 淨付金額
		DETAIL_SORT_FIELD_NAMES.put("netIncome", "NET_INCOME"); // 淨收金額

		DETAIL_SORT_FIELD_NAMES.put("accountNoChk", "ACCOUNT_NO_CHK"); // 帳號檢查碼
		DETAIL_SORT_FIELD_NAMES.put("amountChk", "AMOUNT_CHK"); // 金額檢查碼

		DETAIL_SORT_FIELD_NAMES.put("dealType", "DEAL_TYPE"); // 處理類別
		DETAIL_SORT_FIELD_NAMES.put("customerName", "CUSTOMER_NAME"); // 客戶戶名
		DETAIL_SORT_FIELD_NAMES.put("stockNo", "STOCK_NO"); // 證券代號
		DETAIL_SORT_FIELD_NAMES.put("stockName", "STOCK_NAME"); // 證券名稱



		DETAIL_SORT_FIELD_NAMES.put("chargebackPriority", "CHARGEBACK_PRIORITY"); // 扣款優先種類
		DETAIL_SORT_FIELD_NAMES.put("chargebackPriorityCode", "CHARGEBACK_PRIORITY_CODE"); // 扣款先後序號
		DETAIL_SORT_FIELD_NAMES.put("teller", "TELLER"); // 營業櫃員
		DETAIL_SORT_FIELD_NAMES.put("dealResultCode", "DEAL_RESULT_CODE"); // 處理狀況代號
		DETAIL_SORT_FIELD_NAMES.put("customerId", "CUSTOMER_ID"); // 身份證號
		DETAIL_SORT_FIELD_NAMES.put("securitiesNo", "SECURITIES_NO"); // 券商代號
	}

	/**
	 * 查詢結果隱藏不必要欄位
	 */
	protected Boolean hideQryResultColumns = Boolean.TRUE;	


	/**
	 * 查詢條件
	 */
	protected TempUploadFile tempUploadFile;

	/**
	 * 查詢條件-上傳日期迄
	 */
	@Validate( converter=DateTypeConverter.class)
	protected Date uploaddDateFrom;

	/**
	 * 查詢條件-上傳時間迄
	 */
	@Validate( converter=DateTypeConverter.class)
	protected Date uploadDateTo;

	/**
	 * 查詢條件-檔案類型
	 */
	protected List<String> fileFormats;

	/**
	 * 查詢結果(多筆)
	 */
	protected PaginatedList<TempUploadFile> queryResult;


	/**
	 * 錯誤原因查詢結果(多筆)
	 */
	protected PaginatedList<TempUploadFileError> queryErrorResult;


	/**
	 * 明細查詢結果(多筆)
	 */
	protected PaginatedList queryDetailResult;

	/**
	 * 上傳按鈕，從TempUploadFile Table 複製到 UploadFile.
	 */
	@Validate(required=true, on={"doUpload"})
	protected List<Long> tempUploadFilePks;


	protected List<String> tempUploadFileFormats;

	/**
	 * 約定帳號對象
	 */
	private PreDesignatedAccount preDesignatedAccount;

	@SpringBean("preDesignatedAccountService")
	private PreDesignatedAccountService preDesignatedAccountService;

	/**
	 * 刪除上傳暫存檔
	 */
	@Validate(required=true, on={"doDeleteTempUploadFile", "doViewUploadError", "doViewDetail"})
	protected Long tempUploadFilePk;

	/**
	 * 檔案類型
	 */
	@Validate(required=true, on={"doViewDetail"})
	protected Long fileFormat;

	protected String message;

	protected String errorMessage;

	@DontBind
	@DefaultHandler
	public Resolution doDefault()
	{
		logger.debug("Enter doDefault mehtod.");
		return doQuery(); 
	}

	/**
	 * 查詢上傳暫存檔案
	 * @return
	 */
	public Resolution doQuery()
	{
		logger.debug("Enter doQuery mehtod.");

		/* 設定換頁、排序等條件*/
		String sortCriterion = null == queryResult ? null : queryResult.getSortCriterion();
		List<String> sortFields = getSortFields();
		if (StringUtils.isEmpty(sortCriterion) || null == getSortFieldNames().get(sortCriterion)) // 未設定/找不到 排序條件時候，則以上傳日期為主要排序
			sortCriterion = sortFields.get(0);

		PaginatedList<TempUploadFile> qryCondition = new PaginatedList<TempUploadFile>();
		if (null != queryResult)
		{
			qryCondition.setPageNumber(queryResult.getPageNumber());
			qryCondition.setPageSize(queryResult.getPageSize());
			qryCondition.setSortCriterion(getSortFieldNames().get(sortCriterion));
			qryCondition.setSortDirection(queryResult.getSortDirection());
		}


		if (null == queryResult || StringUtils.isEmpty(queryResult.getSortCriterion()) || !sortFields.contains(queryResult.getSortCriterion()))
		{
			// 以上傳日期由大到小排序
			qryCondition.setSortCriterion(getSortFieldNames().get(sortFields.get(0)));
			qryCondition.setSortDirection(PaginatedList.SORT_DIRECTION_DESC);
		}

		if (null == tempUploadFile)
			tempUploadFile = new TempUploadFile();

		if (! UserUtil.isBankGroup())
		{
			// 非銀行端需加入 群組/證券業者 Group 限制
			tempUploadFile.setGroup(new Group());
			BeanUtils.copyProperties(UserUtil.getUserGroup(), tempUploadFile.getGroup(), new String[]{"users", "roles"});

			/* 加入上傳人員的限制   */
			tempUploadFile.setUploadUser(new User());
			BeanUtils.copyProperties(UserUtil.getUser(), tempUploadFile.getUploadUser(), new String[]{"group", "securities", "roles", "userLoginControl"});
		}

		this.queryResult = invokeServiceToQuery(tempUploadFile, uploaddDateFrom, uploadDateTo, fileFormats, qryCondition);

		if (null == queryResult)
		{
			queryResult = new PaginatedList<TempUploadFile>();
			queryResult.setPageNumber(qryCondition.getPageNumber());
			queryResult.setPageSize(qryCondition.getPageSize());
		}

		this.queryResult.setSortCriterion(sortCriterion);
		this.queryResult.setSortDirection(qryCondition.getSortDirection());

		return new ForwardResolution(getDefaultPage()); 
	}

	/**
	 * 呼叫 Service 查詢上傳紀錄
	 * @param tempUploadFile1
	 * @param uploaddDateFrom1
	 * @param uploadDateTo1
	 * @param fileFormats1
	 * @param qryCondition
	 * @return
	 */
	protected PaginatedList<TempUploadFile> invokeServiceToQuery(
			TempUploadFile tempUploadFile1, Date uploaddDateFrom1,
			Date uploadDateTo1, List<String> fileFormats1,
			PaginatedList<TempUploadFile> qryCondition) {
		return tempUploadFileService.findPaginatedListByTempUploadFile(tempUploadFile1, uploaddDateFrom1, uploadDateTo1, fileFormats1, qryCondition);
	}

	/**
	 * 上傳首頁
	 * @return
	 */
	protected abstract String getDefaultPage();

	/**
	 * 上傳檔案類型
	 * @return
	 */
	public abstract String getUploadFileFormat();


	public abstract FileImportorService<?, ?> getFileImportorService();


	/**
	 * 將檔案上傳至暫存檔中
	 * @return
	 */
	public Resolution doUploadToTemporary()
	{
		logger.debug("Enter doUploadToTemporary mehtod.");

		StringBuffer logNote = new StringBuffer();
		TempUploadFile tempUploadFile = null;
		String noPreDesignatedAccountMsg = "尚未設定約定帳號！請先設定後再執行上傳！";
		
		try {

			// Client 端的檔案名稱
			String fileName = attachment.getFileName();
			logNote.append("檔案名稱: ").append(fileName).append("。");

			// 計算檔案大小
			try {
				long fileSize = attachment.getSize();
				if (fileSize > 1048576)
				{
					logNote.append("大小: ").append(fileSize/1048576).append(" Mb。");
				}
				else if (fileSize > 1024)
				{
					logNote.append("大小: ").append(fileSize/1024).append(" Kb。");
				}
				else
				{
					logNote.append("大小: ").append(fileSize).append(" bytes。");
				}
			}
			catch (Exception e) {
				// do nothing.
			}


			/* Step1: 將上傳檔案檔名改為UUID字串；上傳之檔案存放在  Server 上的檔案名稱 */
			String fileNameOnServer = UUID.randomUUID().toString();

			/* Step2: 設定暫存檔的路徑 ； 暫存檔目錄/日期/群組編號/ */            
			DateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
			String groupNo = UserUtil.getUserGroup().getGroupNo(); 
			// 存放暫存目錄: {temporaryBaseDirectory}/20120420/2148/
			String toTemporaryDirectory = temporaryBaseDirectory + separator + dateFormat.format(new Date()) + separator + groupNo + separator;            
			File toTemporaryDirectoryFile = new File(toTemporaryDirectory);
			// 目錄不存在則建立目錄
			if (!toTemporaryDirectoryFile.exists())
			{
				logger.debug("建立暫存目錄: {}", toTemporaryDirectoryFile);
				try {
					toTemporaryDirectoryFile.mkdirs();
				}
				catch (Exception e) {
					logger.error("上傳檔案發生錯誤,無法建立暫存目錄:", e); //由 log4j 發送Mail
					this.errorMessage = messageSource.getMessage("upload.file.exception", null, "上傳發生錯誤，請重新再試一次，若依就無法上傳，請聯絡網站管理人員，謝謝！", this.getContext().getRequest().getLocale());
					try {

						if (null != attachment)
							attachment.delete();
					} catch (Exception e2) {
						// do nothing.
					}
				}
			}

			// 備份資料目錄: {backupBaseDirectory}/20120420/2148/
			String tobackupBaseDirectory = backupBaseDirectory + separator + dateFormat.format(new Date()) + separator + groupNo + separator;            
			File tobackupBaseDirectoryFile = new File(tobackupBaseDirectory);
			// 目錄不存在則建立目錄
			if (!tobackupBaseDirectoryFile.exists())
			{
				logger.debug("建立備份目錄: {}", tobackupBaseDirectoryFile);
				try {
					tobackupBaseDirectoryFile.mkdirs();
				}
				catch (Exception e) {
					logger.error("上傳檔案發生錯誤,無法建立備份目錄:", e); //由 log4j 發送Mail
					this.errorMessage = messageSource.getMessage("upload.file.exception", null, "上傳發生錯誤，請重新再試一次，若依就無法上傳，請聯絡網站管理人員，謝謝！", this.getContext().getRequest().getLocale());
				}
			}

			String desKey = null;

			ConfirmRule confirmRule = confirmRuleService.findConfirmRuleEnabled(UserUtil.getUserGroup());
			if (null == confirmRule)
			{
				this.errorMessage = messageSource.getMessage("unset.confirm.rule", null, "尚未設定券商流程！請先設定後再執行上傳！", this.getContext().getRequest().getLocale());
			}
			else
			{
				desKey = confirmRule.getDesKey();
			}

			if (StringUtils.isEmpty(this.errorMessage))
			{
				toTemporaryDirectoryFile = null;

				/* Step3: */
				String toDest = toTemporaryDirectory + fileNameOnServer;
				logger.debug("將原始檔案: {} 存至 {}", fileName, toDest);
				File toDestFile = new File(toDest);
				attachment.save(toDestFile);

				/* Step4: 將資訊紀錄到暫存檔中 */
				User uploadUser = UserUtil.getUser();
				tempUploadFile = new TempUploadFile();
				tempUploadFile.setFileFormat(getUploadFileFormat());//上傳檔案類型
				tempUploadFile.setGroup(uploadUser.getGroup());
				tempUploadFile.setFileName(fileName);
				tempUploadFile.setUploadDate(new Date());
				tempUploadFile.setUploadUser(uploadUser);
				tempUploadFile.setFilePathOnServer(toDest);
				tempUploadFile.setFileStatus(TempUploadFile.FILE_STATUS_IN_IMPORT); // 轉入中
				tempUploadFile.setDesKey(desKey);
				tempUploadFile.setFileMd5(FileMD5CheckSumUtil.getInstance().getMD5Checksum(toDest)); // 計算檔案MD5
				tempUploadFileService.addTempUploadFile(tempUploadFile);

				/* Step5: 設定檢核會用到的Object */
				getFileImportorService().setTempUploadFile(tempUploadFile);
				getFileImportorService().setUploadUser(uploadUser);

				/* Step6: 檔名檢查 */
				getFileImportorService().checkFileNameConventions();

				boolean passed = getFileImportorService().isPassed();
				if (! passed)
				{
					this.errorMessage = messageSource.getMessage("upload.file.fail.naming.conventions", null, "上傳失敗！(檔案名稱不符合命名規則)", this.getContext().getRequest().getLocale());
				}
				else
				{

					/* 如果 OK 取得約定帳號, 沒有的話要做處理 提示 類似劵商流程*/
					preDesignatedAccount = preDesignatedAccountService.getPreDesignatedAccountBySecuritiesNo(tempUploadFile.getSecuritiesNo(), tempUploadFile.getBankBracnchNo());

					if (null == preDesignatedAccount){
						throw new Exception(noPreDesignatedAccountMsg);				// 未設定約定帳號
					}else if(preDesignatedAccount.getBankBracnchNo1().equals(tempUploadFile.getBankBracnchNo())){		// 一般上市櫃
						if ( "H".equals(tempUploadFile.getStockType().trim())){ 
							tempUploadFile.setPreDesignatedAccount(preDesignatedAccount.getAccount_No_H1());
						}else if("P".equals(tempUploadFile.getStockType().trim())){	// 調撥
							tempUploadFile.setPreDesignatedAccount(preDesignatedAccount.getAccount_No_P1());
						}else if("R".equals(tempUploadFile.getStockType().trim())){	// 興櫃
							tempUploadFile.setPreDesignatedAccount(preDesignatedAccount.getAccount_No_R1());
						}
					}else if(preDesignatedAccount.getBankBracnchNo2().equals(tempUploadFile.getBankBracnchNo())){
						if ("H".equals(tempUploadFile.getStockType())){				// 一般上市櫃
							tempUploadFile.setPreDesignatedAccount(preDesignatedAccount.getAccount_No_H2());
						}else if("P".equals(tempUploadFile.getStockType())){		// 調撥
							tempUploadFile.setPreDesignatedAccount(preDesignatedAccount.getAccount_No_P2());
						}else if("R".equals(tempUploadFile.getStockType())){		// 興櫃
							tempUploadFile.setPreDesignatedAccount(preDesignatedAccount.getAccount_No_R2());
						}
					}

					if(null == tempUploadFile.getPreDesignatedAccount()){
						throw new Exception(noPreDesignatedAccountMsg); // 未設定約定帳號
					}


					/* Step7: 檢查檔案內容*/
					getFileImportorService().checkFileContent();
					passed = getFileImportorService().isPassed();


					if (passed)
					{
						// 檢查通過，將搬移檔案到備份區
						String toBackup = tobackupBaseDirectory + fileNameOnServer;
						File toBackupFile = new File(toBackup);
						FileUtils.copyFile(toDestFile, toBackupFile);
						tempUploadFile.setFilePathOnServer(toBackup); // 更改資料庫資料
					}

					if (!passed)
					{
						this.errorMessage = messageSource.getMessage("upload.file.fail.content.error", null, "上傳失敗！(檔案內容檢查有誤)", this.getContext().getRequest().getLocale());
					}
					else
					{
						this.message = messageSource.getMessage("upload.file.successed", null, "檔案上傳成功", this.getContext().getRequest().getLocale());
					}
				}
			}


		} catch (Exception e) {
			logger.error("上傳檔案發生錯誤:", e); //由 log4j 發送Mail

			if (null != tempUploadFile)
			{
				tempUploadFile.setFileStatus(TempUploadFile.FILE_STATUS_EXCEPTION);
			}

			try {
				TempUploadFileError tempUploadFileError = new TempUploadFileError();
				tempUploadFileError.setLineNumber(0);
				if (noPreDesignatedAccountMsg.equals(e.getMessage())){
					// "尚未設定約定帳號！請先設定後再執行上傳！"
					tempUploadFileError.setErrorMessage(e.getMessage());
				}
				else{
					tempUploadFileError.setErrorMessage(messageSource.getMessage("import.file.check.content.exception",  null, "檔案格式有誤，請聯絡系統管理員", this.getContext().getRequest().getLocale()));
				}
				tempUploadFileError.setExceptionMessage(e.getMessage());
				tempUploadFileError.setTempUploadFile(tempUploadFile);
				tempUploadFileErrorService.addTempUploadFileError(tempUploadFileError);
			} catch (Exception e1) {
				logger.error("紀錄上傳Exception時發生錯誤:", e1); //由 log4j 發送Mail
			}

			
			if (noPreDesignatedAccountMsg.equals(e.getMessage())){
				// "尚未設定約定帳號！請先設定後再執行上傳！"
				this.errorMessage = messageSource.getMessage("unset.pre.designated.account", null, noPreDesignatedAccountMsg, this.getContext().getRequest().getLocale());
			}
			else{
				this.errorMessage = messageSource.getMessage("upload.file.exception", null, "上傳發生錯誤，請重新再試一次，若依舊無法上傳，請聯絡網站管理人員，謝謝！", this.getContext().getRequest().getLocale());
			}
			
		}
		finally
		{
			if (null != tempUploadFile)
			{
				try {
					tempUploadFileService.updateImportStatus(tempUploadFile);
				} catch (Exception e1) {
					logger.error("紀錄上傳Exception時發生錯誤:", e1); //由 log4j 發送Mail
				}
			}
		}

		return this.doQuery(); 

	}

	/**
	 * 刪除上傳暫存檔
	 * @return
	 */
	public Resolution doDeleteTempUploadFile()
	{
		try {

			getFileImportorService().deleteByTempUploadFilePk( this.tempUploadFilePk);

			this.message = messageSource.getMessage("delete.upload.file.successed", null, "檔案已刪除！", this.getContext().getRequest().getLocale());
		} catch (Exception e) {
			logger.error("刪除上傳檔案發生錯誤:", e); //由 log4j 發送Mail
			this.errorMessage = messageSource.getMessage("delete.upload.file.failed", null, "檔案檔案發生錯誤，請重新再試一次，若依就無法刪除，請聯絡網站管理人員，謝謝！", this.getContext().getRequest().getLocale());
		}

		return this.doQuery(); 
	}

	/**
	 * 從TempUploadFile Table 複製到 UploadFile.
	 * 需發送Mail
	 * @return
	 */
	public Resolution doUpload()
	{
		try {
			if (null != this.tempUploadFilePks)
			{
				logger.error("ConfirmRule");
				ConfirmRule confirmRule = confirmRuleService.findConfirmRuleEnabled(UserUtil.getUserGroup());
				if (null == confirmRule)
				{
					this.errorMessage = messageSource.getMessage("unset.confirm.rule", null, "尚未設定券商流程！請先設定後再執行上傳！", this.getContext().getRequest().getLocale());
				}
				else
				{
					for(Long pk : this.tempUploadFilePks)
					{
						if (null != pk)
						{
							/* 如果 OK 取得約定帳號, 沒有的話要做處理 提示 類似劵商流程 */
							TempUploadFile tempUploadFile = null;
							String noPreDesignatedAccountMsg = "尚未設定約定帳號！請先設定後再執行上傳！";
							
							tempUploadFile = tempUploadFileService.findTempUploadFileByPk(pk);
							preDesignatedAccount = preDesignatedAccountService.getPreDesignatedAccountBySecuritiesNo(tempUploadFile.getSecuritiesNo(), tempUploadFile.getBankBracnchNo());							
							
							if (null == preDesignatedAccount){
								throw new Exception(noPreDesignatedAccountMsg);				// 未設定約定帳號
							}else if(preDesignatedAccount.getBankBracnchNo1().equals(tempUploadFile.getBankBracnchNo())){		// 一般上市櫃
								if ( "H".equals(tempUploadFile.getStockType().trim())){ 
									tempUploadFile.setPreDesignatedAccount(preDesignatedAccount.getAccount_No_H1());
								}else if("P".equals(tempUploadFile.getStockType().trim())){	// 調撥
									tempUploadFile.setPreDesignatedAccount(preDesignatedAccount.getAccount_No_P1());
								}else if("R".equals(tempUploadFile.getStockType().trim())){	// 興櫃
									tempUploadFile.setPreDesignatedAccount(preDesignatedAccount.getAccount_No_R1());
								}
							}else if(preDesignatedAccount.getBankBracnchNo2().equals(tempUploadFile.getBankBracnchNo())){
								if ("H".equals(tempUploadFile.getStockType())){				// 一般上市櫃
									tempUploadFile.setPreDesignatedAccount(preDesignatedAccount.getAccount_No_H2());
								}else if("P".equals(tempUploadFile.getStockType())){		// 調撥
									tempUploadFile.setPreDesignatedAccount(preDesignatedAccount.getAccount_No_P2());
								}else if("R".equals(tempUploadFile.getStockType())){		// 興櫃
									tempUploadFile.setPreDesignatedAccount(preDesignatedAccount.getAccount_No_R2());
								}
							}else{
								tempUploadFile.setPreDesignatedAccount(null);
							}
							
							if(null == tempUploadFile.getPreDesignatedAccount()){
								
								throw new Exception(noPreDesignatedAccountMsg); // 未設定約定帳號
								
							}else{
								// 將temp資料轉入正式table
								try {
									getFileImportorService().moveToUploadFile(pk, confirmRule.getCheckCount(), confirmRule.getConfirmCount(), tempUploadFile.getPreDesignatedAccount());
								} catch (Exception e) {									
									if ("尚未設定約定帳號！請先設定後再執行上傳！".equals(e.getMessage())){
										this.errorMessage = messageSource.getMessage("unset.pre.designated.account", null, "尚未設定約定帳號！請先設定後再執行上傳！", this.getContext().getRequest().getLocale());
									}
									else{
										this.errorMessage = messageSource.getMessage("upload.file.exception", null, "上傳發生錯誤，請重新再試一次，若依就無法上傳，請聯絡網站管理人員，謝謝！", this.getContext().getRequest().getLocale());
									}
								}
								
							} // if(null == tempUploadFile.getPreDesignatedAccount())

						} // if (null != pk)
					}

					this.message = messageSource.getMessage("upload.file.successed", null, "檔案上傳成功", this.getContext().getRequest().getLocale());
				}
			}
		} catch (Exception e) {
			logger.error("",e);
			//this.errorMessage = messageSource.getMessage("upload.file.exception", null, "上傳發生錯誤，請重新再試一次，若依就無法上傳，請聯絡網站管理人員，謝謝！", this.getContext().getRequest().getLocale());
			if ("尚未設定約定帳號！請先設定後再執行上傳！".equals(e.getMessage())){
				this.errorMessage = messageSource.getMessage("unset.pre.designated.account", null, "尚未設定約定帳號！請先設定後再執行上傳！", this.getContext().getRequest().getLocale());
			}else{
				this.errorMessage = messageSource.getMessage("upload.file.exception", null, "上傳發生錯誤，請重新再試一次，若依就無法上傳，請聯絡網站管理人員，謝謝！", this.getContext().getRequest().getLocale());
			}
		}

		return this.doQuery(); 
	}

	/**
	 * 檢視錯誤原因
	 * @return
	 */
	public Resolution doViewUploadError()
	{
		/* 設定換頁、排序等條件*/
		String sortCriterion = null == queryErrorResult ? null : queryErrorResult.getSortCriterion();
		List<String> sortFields = getErrorSortFields();
		if (StringUtils.isEmpty(sortCriterion) || null == ERROR_SORT_FIELD_NAMES.get(sortCriterion)) // 未設定/找不到 排序條件時候，則以上傳日期為主要排序
			sortCriterion = sortFields.get(0);

		PaginatedList<TempUploadFileError> qryCondition = new PaginatedList<TempUploadFileError>();
		if (null != queryErrorResult)
		{
			qryCondition.setPageNumber(queryErrorResult.getPageNumber());
			qryCondition.setPageSize(queryErrorResult.getPageSize());
			qryCondition.setSortCriterion(ERROR_SORT_FIELD_NAMES.get(sortCriterion));
			qryCondition.setSortDirection(queryErrorResult.getSortDirection());
		}		

		queryErrorResult = tempUploadFileErrorService.findPaginatedListByTempUploadFilePk(tempUploadFilePk, qryCondition);

		if (null == queryErrorResult)
		{
			queryErrorResult = new PaginatedList<TempUploadFileError>();
			queryErrorResult.setPageNumber(qryCondition.getPageNumber());
			queryErrorResult.setPageSize(qryCondition.getPageSize());
		}

		this.queryErrorResult.setSortCriterion(sortCriterion);
		this.queryErrorResult.setSortDirection(qryCondition.getSortDirection());

		return new ForwardResolution(UPLOAD_ERROR_JSP); 
	}

	public Resolution doViewDetail()
	{
		/* 設定換頁、排序等條件*/
		String sortCriterion = null == queryDetailResult ? null : queryDetailResult.getSortCriterion();
		List<String> sortFields = getDetailSortFields();
		if (StringUtils.isEmpty(sortCriterion) || null == DETAIL_SORT_FIELD_NAMES.get(sortCriterion)) // 未設定/找不到 排序條件時候，則以上傳日期為主要排序
			sortCriterion = sortFields.get(0);

		PaginatedList qryCondition = new PaginatedList();

		if (null != queryDetailResult)
		{
			qryCondition.setPageNumber(queryDetailResult.getPageNumber());
			qryCondition.setPageSize(queryDetailResult.getPageSize());
			qryCondition.setSortCriterion(DETAIL_SORT_FIELD_NAMES.get(sortCriterion));
			qryCondition.setSortDirection(queryDetailResult.getSortDirection());
		}		

		queryDetailResult = getFileImportorService().findPaginatedListByTempUploadFilePk(tempUploadFilePk, qryCondition);

		if (null == queryDetailResult)
		{
			queryDetailResult = new PaginatedList();
			queryDetailResult.setPageNumber(qryCondition.getPageNumber());
			queryDetailResult.setPageSize(qryCondition.getPageSize());
		}

		this.queryDetailResult.setSortCriterion(sortCriterion);
		this.queryDetailResult.setSortDirection(qryCondition.getSortDirection());

		return new ForwardResolution(UPLOAD_DETAIL_JSP); 
	}

	
	public Resolution doViewChkDetail()
	
	
	{
		/* 設定換頁、排序等條件*/
		String sortCriterion = null == queryDetailResult ? null : queryDetailResult.getSortCriterion();
		List<String> sortFields = getDetailSortFields();
		if (StringUtils.isEmpty(sortCriterion) || null == DETAIL_SORT_FIELD_NAMES.get(sortCriterion)) // 未設定/找不到 排序條件時候，則以上傳日期為主要排序
			sortCriterion = sortFields.get(0);
		
		PaginatedList qryCondition = new PaginatedList();
		
		if (null != queryDetailResult)
		{
			qryCondition.setPageNumber(queryDetailResult.getPageNumber());
			qryCondition.setPageSize(queryDetailResult.getPageSize());
			qryCondition.setSortCriterion(DETAIL_SORT_FIELD_NAMES.get(sortCriterion));
			qryCondition.setSortDirection(queryDetailResult.getSortDirection());
		}		
		
		queryDetailResult = getFileImportorService().findChkPaginatedListByUploadFilePk(tempUploadFilePk, qryCondition);
		
		if (null == queryDetailResult)
		{
			queryDetailResult = new PaginatedList();
			queryDetailResult.setPageNumber(qryCondition.getPageNumber());
			queryDetailResult.setPageSize(qryCondition.getPageSize());
		}
			
		this.queryDetailResult.setSortCriterion(sortCriterion);
		this.queryDetailResult.setSortDirection(qryCondition.getSortDirection());
		
		return new ForwardResolution(UPLOAD_CHK_DETAIL_JSP); 
	}
	
	protected Map<String, String> getSortFieldNames(){
		return BaseUploadActionBean.SORT_FIELD_NAMES;
	}

	public List<String> getDetailSortFields()
	{
		List<String> result = new ArrayList<String>();
		CollectionUtils.addAll(result, DETAIL_SORT_FIELD_NAMES.keySet().iterator()	);
		return result;
	}

	public List<String> getErrorSortFields()
	{
		List<String> result = new ArrayList<String>();
		CollectionUtils.addAll(result, ERROR_SORT_FIELD_NAMES.keySet().iterator()	);
		return result;
	}

	public List<String> getSortFields()
	{
		List<String> result = new ArrayList<String>();
		CollectionUtils.addAll(result, getSortFieldNames().keySet().iterator()	);
		return result;
	}

	public void setDetailNavigator()
	{
		if (null != queryDetailResult)
		{
			int sortDirection = queryDetailResult.getSortDirection();  //2 : ascending, else: descending
			String sortSpan = "<span class=\"ui-icon ui-icon-circle-triangle-n\"></span>"; //由小到大
			if (1 == sortDirection)
			{
				sortSpan = "<span class=\"ui-icon ui-icon-circle-triangle-s\"></span>"; //由大到小
			}

			String sortCriterion = queryDetailResult.getSortCriterion();
			if (null!= sortCriterion && null != DETAIL_SORT_FIELD_NAMES.get(sortCriterion))
			{
				this.getContext().getRequest().setAttribute(sortCriterion+"SortedClass", 1==sortDirection?"sortDesc":"sortAsc");
				this.getContext().getRequest().setAttribute(sortCriterion+"SortedSpan", sortSpan);
			}
			else
			{
				sortCriterion = getDetailSortFields().get(0);
				this.getContext().getRequest().setAttribute(sortCriterion+"SortedClass", 1==sortDirection?"sortDesc":"sortAsc");
				this.getContext().getRequest().setAttribute(sortCriterion+"SortedSpan", sortSpan);
			}


			// 上下頁鈕處理
			int lastPageNumber = queryDetailResult.getTotalPageCount();
			int currentPageNumber = queryDetailResult.getPageNumber();
			int prePageNumber = currentPageNumber - 1;
			int nextPageNumber = currentPageNumber + 1;

			this.getContext().getRequest().setAttribute("lastPageNumber", new Integer(lastPageNumber));
			this.getContext().getRequest().setAttribute("currentPageNumber", new Integer(currentPageNumber));
			this.getContext().getRequest().setAttribute("prePageNumber", new Integer(prePageNumber));
			this.getContext().getRequest().setAttribute("nextPageNumber", new Integer(nextPageNumber));
		}
	}

	public void setErrorNavigator()
	{
		if (null != queryErrorResult)
		{
			int sortDirection = queryErrorResult.getSortDirection();  //2 : ascending, else: descending
			String sortSpan = "<span class=\"ui-icon ui-icon-circle-triangle-n\"></span>"; //由小到大
			if (1 == sortDirection)
			{
				sortSpan = "<span class=\"ui-icon ui-icon-circle-triangle-s\"></span>"; //由大到小
			}

			String sortCriterion = queryErrorResult.getSortCriterion();
			if (null!= sortCriterion && null != ERROR_SORT_FIELD_NAMES.get(sortCriterion))
			{
				this.getContext().getRequest().setAttribute(sortCriterion+"SortedClass", 1==sortDirection?"sortDesc":"sortAsc");
				this.getContext().getRequest().setAttribute(sortCriterion+"SortedSpan", sortSpan);
			}
			else
			{
				sortCriterion = getErrorSortFields().get(0);
				this.getContext().getRequest().setAttribute(sortCriterion+"SortedClass", 1==sortDirection?"sortDesc":"sortAsc");
				this.getContext().getRequest().setAttribute(sortCriterion+"SortedSpan", sortSpan);
			}


			// 上下頁鈕處理
			int lastPageNumber = queryErrorResult.getTotalPageCount();
			int currentPageNumber = queryErrorResult.getPageNumber();
			int prePageNumber = currentPageNumber - 1;
			int nextPageNumber = currentPageNumber + 1;

			this.getContext().getRequest().setAttribute("lastPageNumber", new Integer(lastPageNumber));
			this.getContext().getRequest().setAttribute("currentPageNumber", new Integer(currentPageNumber));
			this.getContext().getRequest().setAttribute("prePageNumber", new Integer(prePageNumber));
			this.getContext().getRequest().setAttribute("nextPageNumber", new Integer(nextPageNumber));
		}
	}

	public void setNavigator()
	{
		if (null != queryResult)
		{
			int sortDirection = queryResult.getSortDirection();  //2 : ascending, else: descending
			String sortSpan = "<span class=\"ui-icon ui-icon-circle-triangle-n\"></span>"; //由小到大
			if (1 == sortDirection)
			{
				sortSpan = "<span class=\"ui-icon ui-icon-circle-triangle-s\"></span>"; //由大到小
			}

			String sortCriterion = queryResult.getSortCriterion();
			if (null!= sortCriterion && null != getSortFieldNames().get(sortCriterion))
			{
				this.getContext().getRequest().setAttribute(sortCriterion+"SortedClass", 1==sortDirection?"sortDesc":"sortAsc");
				this.getContext().getRequest().setAttribute(sortCriterion+"SortedSpan", sortSpan);
			}
			else
			{
				sortCriterion = getSortFields().get(0);
				this.getContext().getRequest().setAttribute(sortCriterion+"SortedClass", 1==sortDirection?"sortDesc":"sortAsc");
				this.getContext().getRequest().setAttribute(sortCriterion+"SortedSpan", sortSpan);
			}


			// 上下頁鈕處理
			int lastPageNumber = queryResult.getTotalPageCount();
			int currentPageNumber = queryResult.getPageNumber();
			int prePageNumber = currentPageNumber - 1;
			int nextPageNumber = currentPageNumber + 1;

			this.getContext().getRequest().setAttribute("lastPageNumber", new Integer(lastPageNumber));
			this.getContext().getRequest().setAttribute("currentPageNumber", new Integer(currentPageNumber));
			this.getContext().getRequest().setAttribute("prePageNumber", new Integer(prePageNumber));
			this.getContext().getRequest().setAttribute("nextPageNumber", new Integer(nextPageNumber));
		}
	}

	public FileBean getAttachment() {
		return attachment;
	}

	public void setAttachment(FileBean attachment) {
		this.attachment = attachment;
	}

	public PaginatedList<TempUploadFile> getQueryResult() {
		return queryResult;
	}

	public void setQueryResult(PaginatedList<TempUploadFile> queryResult) {
		this.queryResult = queryResult;
	}

	public Long getTempUploadFilePk() {
		return tempUploadFilePk;
	}

	public void setTempUploadFilePk(Long tempUploadFilePk) {
		this.tempUploadFilePk = tempUploadFilePk;
	}

	public List<Long> getTempUploadFilePks() {
		return tempUploadFilePks;
	}

	public void setTempUploadFilePks(List<Long> tempUploadFilePks) {
		this.tempUploadFilePks = tempUploadFilePks;
	}

	public PaginatedList<TempUploadFileError> getQueryErrorResult() {
		return queryErrorResult;
	}

	public void setQueryErrorResult(
			PaginatedList<TempUploadFileError> queryErrorResult) {
		this.queryErrorResult = queryErrorResult;
	}

	public String getMessage() {
		return message;
	}

	public String getErrorMessage() {
		return errorMessage;
	}

	public List<String> getTempUploadFileFormats() {
		return tempUploadFileFormats;
	}

	public void setTempUploadFileFormats(List<String> tempUploadFileFormats) {
		this.tempUploadFileFormats = tempUploadFileFormats;
	}

	public PaginatedList getQueryDetailResult() {
		return queryDetailResult;
	}

	public void setQueryDetailResult(PaginatedList queryDetailResult) {
		this.queryDetailResult = queryDetailResult;
	}

	public Boolean getHideQryResultColumns() {
		return hideQryResultColumns;
	}

	public void setHideQryResultColumns(Boolean hideQryResultColumns) {
		this.hideQryResultColumns = hideQryResultColumns;
	}


}
